package test.crane;

import ptolemy.actor.*;
import ptolemy.kernel.*;
import ptolemy.kernel.util.*;
import ptolemy.data.*;
import ptolemy.data.type.*;

//////////////////////////////////////////////////////////////////////////
//// Check2
/**

@author Ivan Jeukens
@version v 0.1 07/02/2002
*/
public class CheckMinMaxPos extends TypedAtomicActor {

    public CheckMinMaxPos(CompositeEntity container, String name) throws
            IllegalActionException, NameDuplicationException {
        super(container, name);

        shutdown = new TypedIOPort(this, "shutdown", true, false);
        shutdown.setTypeEquals(BaseType.GENERAL);

        trigger = new TypedIOPort(this, "trigger", true, false);
        trigger.setTypeEquals(BaseType.GENERAL);

        swposcarmin = new TypedIOPort(this, "swposcarmin", true, false);
        swposcarmin.setTypeEquals(BaseType.BOOLEAN);

        swposcarmax = new TypedIOPort(this, "swposcarmax", true, false);
        swposcarmax.setTypeEquals(BaseType.BOOLEAN);

        emstop_input = new TypedIOPort(this, "emstop_input", true, false);
        emstop_input.setTypeEquals(BaseType.GENERAL);

        emstop = new TypedIOPort(this, "emstop", false, true);
        emstop.setTypeEquals(BaseType.GENERAL);

        new Attribute(this, "_nonStrictMarker");
    }

    public TypedIOPort trigger;
    public TypedIOPort shutdown;
    public TypedIOPort swposcarmin;
    public TypedIOPort swposcarmax;
    public TypedIOPort emstop_input;

    public TypedIOPort emstop;

    ///////////////////////////////////////////////////////////////////
    ////                         public methods                    ////

    public void pruneDependencies() {
        super.pruneDependencies();

        removeDependency(trigger, emstop);
        removeDependency(shutdown, emstop);
        removeDependency(emstop_input, emstop);
    }
    
    public void initialize() throws IllegalActionException  {
        super.initialize();
        _reset();
    }

    public void fire() throws IllegalActionException {

        if(_state == RUNNING) {
            if(swposcarmin.isKnown() && swposcarmax.isKnown() && !emstop.isKnown()) {
            //if(swposcarmin.isKnown() && swposcarmax.isKnown()) {
                if(swposcarmin.hasToken(0) && swposcarmax.hasToken(0)) {
                    boolean _min = ((BooleanToken) swposcarmin.get(0)).booleanValue();
                    boolean _max = ((BooleanToken) swposcarmax.get(0)).booleanValue();

                    if(_min || _max) {      // tem um evento
                        _count++;
                    }
                    else {
                        _count = 0;
                    }

                    if(_count > 10) {
                        emstop.broadcast(new Token());
                        System.out.println("Minmax...emergency stop!");
                        _reset();
                    }

                    /*
                    if(_count > 0) {   // so atualiza se um evento true deu inicio
                        _count++;
                    }
                    if(_count == 50) {   // deu os 100ms
                        if(_maxSensorCount > 10 ||
                           _sensorCount > 10) {
                            emstop.broadcast(new Token());
                            System.out.println("Minmax...emergency stop!");
                            _reset();
                        }
                        _count = 0;
                        _sensorCount = 0;
                        _maxSensorCount = 0;
                    }
                    else {
                        if(_min || _max) {      // tem um evento
                            _sensorCount++;
                            if(_count == 0) {
                                _count = 1;
                            }
                        }

                        if(!_min && !_max && _count > 0) {    // nao tem mais , e estava contando 
                            if(_sensorCount > _maxSensorCount) {
                                _maxSensorCount = _sensorCount;
                            }
                            _sensorCount = 0;
                        }
                    }*/
                }
            }
        }

        if(swposcarmin.isKnown() && swposcarmax.isKnown() && !emstop.isKnown()) {
            emstop.broadcastClear();
        }
    }

    public boolean postfire() throws IllegalActionException {
        switch(_state) {
            
            case READY : {
                if(trigger.isKnown() && shutdown.isKnown()) {
                    if(trigger.hasToken(0) && !shutdown.hasToken(0)) {
                        _state = RUNNING;
                    }
                }
            } break;

            case RUNNING: {
                if(shutdown.isKnown()) {
                    if(shutdown.hasToken(0)) {
                        _reset();
                        break;
                    }
                }

                if(emstop_input.isKnown()) {
                    if(emstop_input.hasToken(0)) {
                        _reset();
                    }
                }
            } break;
        }

        return true;
    }

    ///////////////////////////////////////////////////////////////////
    ////                        private methods                    ////

    private void _reset() {
        _state = READY;
        _count = 0;
        _sensorCount = 0;
        _maxSensorCount = 0;
    }

    ///////////////////////////////////////////////////////////////////
    ////                      private variables                    ////

    private int _state;

    private int _count;
    private int _sensorCount;
    private int _maxSensorCount;

    private static final int READY = 1;
    private static final int RUNNING = 2;
}
